package com.futuremind.recyclerviewfastscroll.viewprovider;


import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.components.Component;

/**
 * 动画管理类
 *
 * @since 2021-03-10
 */
public class VisibilityAnimationManager {
    protected final Component view;

    protected AnimatorProperty hideAnimator;
    protected AnimatorProperty showAnimator;

    private float pivotXRelative;
    private float pivotYRelative;

    /**
     * @param view Component
     * @param showAnimator 显示动画
     * @param hideAnimator 隐藏动画
     * @param pivotXRelative Component X中心轴
     * @param pivotYRelative Component Y中心轴
     * @param hideDelay 动画启动延时
     */
    protected VisibilityAnimationManager(final Component view, AnimatorProperty showAnimator, AnimatorProperty hideAnimator, float pivotXRelative, float pivotYRelative, int hideDelay) {
        this.view = view;
        this.pivotXRelative = pivotXRelative;
        this.pivotYRelative = pivotYRelative;
        this.hideAnimator = hideAnimator;
        this.hideAnimator.setDelay(hideDelay);
        this.hideAnimator.setTarget(view);
        this.showAnimator = showAnimator;
        this.showAnimator.setTarget(view);
        this.hideAnimator.setStateChangedListener(new Animator.StateChangedListener() {
            boolean wasCanceled;

            @Override
            public void onStart(Animator animator) {
            }

            @Override
            public void onStop(Animator animator) {
                wasCanceled = false;
                view.setVisibility(Component.INVISIBLE);
            }

            @Override
            public void onCancel(Animator animator) {
                wasCanceled = true;
            }

            @Override
            public void onEnd(Animator animator) {
                if (!wasCanceled) {
                    view.setVisibility(Component.INVISIBLE);
                }
                wasCanceled = false;
            }

            @Override
            public void onPause(Animator animator) {
            }

            @Override
            public void onResume(Animator animator) {
            }
        });
        updatePivot();
    }


    /**
     * 启动展示动画
     */
    public void show() {
        hideAnimator.cancel();

        if (view.getVisibility() == Component.INVISIBLE) {
            view.setVisibility(Component.VISIBLE);
            updatePivot();
            showAnimator.start();
        }
    }

    /**
     * 启动隐藏动画
     */
    public void hide() {
        updatePivot();
        hideAnimator.start();
    }

    /**
     * 更新控件中心点坐标
     */
    protected void updatePivot() {
        view.setPivotX(pivotXRelative * view.getWidth());
        view.setPivotY(pivotYRelative * view.getHeight());
    }

    public static abstract class AbsBuilder<T extends VisibilityAnimationManager> {
        protected final Component view;
        protected AnimatorProperty showAnimator;
        protected AnimatorProperty hideAnimator;
        protected int hideDelay = 1000;
        protected float pivotX = 0.5f;
        protected float pivotY = 0.5f;

        /**
         * builder
         *
         * @param view 动画组件
         */
        public AbsBuilder(Component view) {
            this.view = view;
            initDefaultAnimator();
        }

        /**
         * 设置显示动画
         *
         * @param showAnimatorResource 显示动画
         * @return this
         */
        public AbsBuilder<T> withShowAnimator(AnimatorProperty showAnimatorResource) {
            this.showAnimator = showAnimatorResource;
            return this;
        }

        /**
         * 设置隐藏动画
         *
         * @param hideAnimatorResource 隐藏动画
         * @return this;
         */
        public AbsBuilder<T> withHideAnimator(AnimatorProperty hideAnimatorResource) {
            this.hideAnimator = hideAnimatorResource;
            return this;
        }

        /**
         * 设置延迟时间
         *
         * @param hideDelay 延迟时间
         * @return this;
         */
        public AbsBuilder<T> withHideDelay(int hideDelay) {
            this.hideDelay = hideDelay;
            return this;
        }

        /**
         * 设置X轴中心点
         *
         * @param pivotX X轴中心点
         * @return this;
         */
        public AbsBuilder<T> withPivotX(float pivotX) {
            this.pivotX = pivotX;
            return this;
        }

        /**
         * 设置Y轴中心点
         *
         * @param pivotY Y轴中心点
         * @return this;
         */
        public AbsBuilder<T> withPivotY(float pivotY) {
            this.pivotY = pivotY;
            return this;
        }

        public void initDefaultAnimator() {
            showAnimator = new AnimatorProperty().
                scaleX(1).scaleY(1).alpha(1).setDuration(200).setCurveType(Animator.CurveType.ACCELERATE);
            hideAnimator = new AnimatorProperty().
                scaleX(0).scaleY(0).alpha(0).setDuration(200).setCurveType(Animator.CurveType.ACCELERATE);
        }

        public abstract T build();
    }

    public static class Builder extends AbsBuilder<VisibilityAnimationManager> {
        public Builder(Component view) {
            super(view);
        }

        public VisibilityAnimationManager build() {
            return new VisibilityAnimationManager(view, showAnimator, hideAnimator, pivotX, pivotY, hideDelay);
        }
    }
}
